﻿using SvnAPI.Base.Enumerator;
using SvnAPI.Base.Exception;
using SvnAPI.Base.Extension;
using SvnAPI.Command.Interface;
using System;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.IO;

namespace SvnAPI.Command.Base
{
    /// <summary>
    /// Class to execute the specific command on svn tools and execute the process
    /// to call the executable of that command and wait for the result. 
    /// </summary>
    public class SvnRunCommand : IRunCommand
    {
        #region Properties

        /// <summary>
        /// File Name of svn tool to execute the command.
        /// </summary>
        public String FileName { get; set; }

        /// <summary>
        /// Arguments to execute the command.
        /// </summary>
        public String Arguments { get; set; }

        #endregion

        #region Constructor

        /// <summary>
        /// Constructor for the class.
        /// </summary>
        public SvnRunCommand(Enum commandToolType)
        {
            String env = Environment.GetEnvironmentVariable("SVN_SERVER", EnvironmentVariableTarget.Machine).EmptyNull();
            String att = commandToolType.GetDescription<DisplayAttribute>().EmptyNull();

            this.FileName = Path.Combine(env, att);
        }

        /// <summary>
        /// Constructor for the class.
        /// </summary>
        public SvnRunCommand(Enum commandToolType, String arguments)
        {
            String env = Environment.GetEnvironmentVariable("SVN_SERVER", EnvironmentVariableTarget.Machine).EmptyNull();
            String att = commandToolType.GetDescription<DisplayAttribute>().EmptyNull();

            this.FileName = Path.Combine(env, att);
            this.Arguments = arguments;
        }

        #endregion

        #region Methods

        /// <summary>
        /// Mehod to execute the command with parameters requireds and get the result on Error and Output.
        /// </summary>
        public virtual IResult Run()
        {
            try
            {
                if (File.Exists(FileName))
                {
                    ProcessStartInfo startInfo = new ProcessStartInfo()
                    {
                        FileName = this.FileName,
                        Arguments = this.Arguments,
                        CreateNoWindow = true,
                        UseShellExecute = false,
                        RedirectStandardError = true,
                        RedirectStandardOutput = true
                    };

                    using (Process process = new Process() { StartInfo = startInfo })
                    {
                        process.Start();
                        process.WaitForExit();

                        String error = process.StandardError.ReadToEnd().Trim();
                        String output = process.StandardOutput.ReadToEnd().Trim();
                        
                        return new Result()
                        {
                            Error = error,
                            Output = output,
                            ResultType = error != String.Empty ? ResultType.error : ResultType.output
                        };
                    }
                }
                else
                {
                    throw new CommandException(this, FileName);
                }                
            }
            catch (Exception)
            {
                throw;
            }
        }

        #endregion
    }
}